package jee.boot.module.file.local;

import jee.boot.common.basic.BaseConfig;
import jee.boot.common.basic.ServiceException;
import jee.boot.common.standard.DocumentStorageClient;
import jee.boot.common.utils.DateUtils;
import jee.boot.common.utils.FileUtils;
import jee.boot.common.utils.SpringContextHolder;
import jee.boot.entity.file.Attachment;
import jee.boot.module.file.attachment.service.AttachmentService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.Date;
import java.util.UUID;

/**
 * 文件的本地存储方式
 */
public class LocalFileStore implements DocumentStorageClient {
    private Logger logger= LoggerFactory.getLogger(getClass());
    private BaseConfig baseConfig;
    private AttachmentService attachmentService;
    public LocalFileStore(BaseConfig baseConfig) {
        this.baseConfig = baseConfig;
    }
    /**
     * 上传形式的文件上传
     *
     * @param file 上传形式的文件
     * @return 附件ID, 可以通过这个id下载附件
     */
    public Attachment uploadFromMultipartFile(MultipartFile file){
        // 存储附件数据
        Attachment attachment = new Attachment();
        attachment.setFileName(file.getOriginalFilename());//文件真实名称
        attachment.setFileType(FileUtils.getFileExtension(file.getOriginalFilename()));//文件拓展名
        attachment.setContentType(file.getContentType());//文件类型
        attachment.setFileId(UUID.randomUUID().toString().replaceAll("-", ""));//文件id(存储的文件名称)
        attachment.setSavePath(getSavePath());//存储目录
        // 存储附件文件
        logger.info("本地存储文件:"+getFullPath(attachment));
        File dist = new File(getFullPath(attachment));
        try {
            FileUtils.storeFile(file.getInputStream(), dist);
        } catch (IOException e) {
            logger.error(e.getMessage(),e);
            throw new ServiceException(1401);
        }
        getAttachmentService().save(attachment);
        return attachment;
    }

    /**
     * 输入流上传至文件服务器
     *
     * @param inputStream 输入数据流
     * @param fileName    文件名
     * @return 附件ID, 可以通过这个id下载附件
     */
    @Override
    public Attachment uploadFromInputStream(InputStream inputStream, String fileName) {
        // 存储附件数据
        Attachment attachment = new Attachment();
        attachment.setFileName(fileName);//文件真实名称
        attachment.setFileType(FileUtils.getFileExtension(fileName));//文件拓展名
        attachment.setContentType(null);//文件类型
        attachment.setFileId(UUID.randomUUID().toString().replaceAll("-", ""));//文件id(存储的文件名称)
        attachment.setSavePath(getSavePath());//存储目录
        getAttachmentService().save(attachment);

        // 存储附件文件
        logger.info("本地存储文件:"+getFullPath(attachment));
        File dist = new File(getFullPath(attachment));
        try {
            FileUtils.storeFile(inputStream, dist);
        } catch (IOException e) {
            logger.error(e.getMessage(),e);
            throw new ServiceException(1401);
        }
        return attachment;

    }

    /**
     * 文件上传至文件服务器
     *
     * @param file 临时文件
     * @return 附件ID, 可以通过这个id下载附件
     */
    @Override
    public Attachment uploadFromFile(File file) {
        try {
           return uploadFromInputStream(new FileInputStream(file), file.getName());
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            throw new ServiceException(1401);
        }
    }

    /**
     * 从文件服务器下载一个文件
     *
     * @param attachmentId 文件名称
     */
    @Override
    public File downloadToFile(String attachmentId) throws FileNotFoundException {
        Attachment attachment = getAttachmentService().get(new Attachment(attachmentId));
        if(attachment==null){
            logger.error("附件不存在:"+attachmentId);
            throw new FileNotFoundException(attachmentId);
        }
        File file = new File(getFullPath(attachment));
        logger.info("本地下载文件:"+file.getPath());
        if (!file.exists()) {
            logger.error("文件不存在:"+file.getPath());
            throw new FileNotFoundException(file.getPath());
        }
        return file;
    }

    /**
     * 从文件服务器下载一个文件到输出流
     *
     * @param attachmentId 文件名称
     */
    @Override
    public OutputStream downloadToOutputStream(String attachmentId) throws FileNotFoundException {
        return new FileOutputStream(downloadToFile(attachmentId));
    }

    /**
     * 删除文件
     *
     * @param attachmentId 文件名称
     */
    @Override
    public void deleteFile(String attachmentId) throws FileNotFoundException {
        Attachment attachment = getAttachmentService().get(new Attachment(attachmentId));
        if(attachment==null){
            logger.error("附件不存在:"+attachmentId);
            throw new FileNotFoundException(attachmentId);
        }
        logger.info("本地删除文件:"+getFullPath(attachment));
        FileUtils.deleteFile(getFullPath(attachment));
        getAttachmentService().delete(new Attachment(attachmentId));
    }

    /**
     * 附件数据存储服务
     * @return
     */
    public AttachmentService getAttachmentService() {
        if(attachmentService ==null){
            attachmentService = SpringContextHolder.getBean(AttachmentService.class);
        }
        return attachmentService;
    }

    /**
     * 本地存储按/年/月/日 分目录进行存储 eq: ${basePath}/2020/05/27
     * @return
     */
    public String getSavePath(){
        String path = DateUtils.formatDate(new Date(), "yyyy" + File.separator + "MM" + File.separator + "dd"+ File.separator );
        return path;
    }

    /**
     * 获取完整路径
     * @param attachment
     * @return
     */
    public String getFullPath(Attachment attachment){
        return baseConfig.getBasePath() + attachment.getSavePath()+attachment.getFileId()+"."+attachment.getFileType();
    }
}
